const buildScrapeConfig = (element) => {
	let id = new Date().getTime();
	let props = findDefaultProps(element);
	let routes = findElementRoutes(element);
	let dataInfo = retrieveDataByProps(element, props);
	return {
		id: id,
		name: 'the name of new data',
		data: dataInfo.propValue,
		routes: routes,
		useRoute: routes.length - 1,
		props: props,
		useProp: dataInfo.useProp
	};

};


const findElementRoutes = (element) => {
	let currentElement = element;
	let parentElement = currentElement.parentElement;
	let pathList = [];	
	while(null != currentElement){
		let id = currentElement.id;
		let tagName = currentElement.tagName;
		let classes = Array.from(currentElement.classList);
		let parentElement = currentElement.parentElement;
		let siblings = null != parentElement ? Array.from(parentElement.children) : [currentElement];
		let index = siblings.indexOf(currentElement);
		let route = {
			id: id,
			index: index,
			classes: classes,
			tagName: tagName,
		};
		
		pathList.push(route);

		currentElement = parentElement;

	}

	return pathList.reverse();

};

const retrieveDataByProps = (element, props) => {
	let useProp = '';
	let propValue = '' ;
	let usedProps = 0;
	while(usedProps < props.length){
		useProp = props[usedProps];
		propValue = retrievePropData(element, useProp);
		if(!util.sIsEmpty(propValue)){
			break;
		}
		usedProps = usedProps + 1;
	}

	return {
		useProp: useProp,
		propValue: propValue,
	};

};

const util = {
	sIsEmpty: (str) => {
		return null == str || '' == str || '' == str.trim();
	}

};

const retrievePropData = (element, prop) => {
	if('src' == prop){
		return element.src;
	}
	if('href' == prop){
		return element.href;
	}
	if('text' == prop){
		return element.innerText;
	}
	if('html' == prop){
		return element.innerHTML;
	}
	if('self' == prop){
		return element.outerHTML;
	}
	return '';

};

const NODE_TYPE_ELEMENT = 1;
const NODE_TYPE_ATTRIBUTE = 2;
const NODE_TYPE_TEXT = 3;
const NODE_TYPE_CDATA = 4;
const NODE_TYPE_INSTRUCTION = 7;
const NODE_TYPE_COMMENT = 8;
const NODE_TYPE_DOCUMENT = 9;
const NODE_TYPE_DOC_TYPE = 10;
const NODE_TYPE_DOC_FRAGMENT = 11;
const NODE_TYPE_DEPRECATED_ENTITY = 6;
const NODE_TYPE_DEPRECATED_ENTITY_REFERENCE = 5;
const NODE_TYPE_DEPRECATED_NOTATION = 12;
const findDefaultProps = (element) => {
	let type = element.nodeType;
	let tagName = element.tagName;
	if(NODE_TYPE_TEXT == type){
		return ['text'];
	}
	if(NODE_TYPE_ELEMENT == type){
		return findTagDefaultProps(tagName);
	}
	return '';

};

const srcPropTags = ['img', 'audio', 'video', 'script'];
const hrefPropTags = ['a', 'link'];
const findTagDefaultProps = (tagName) => {
	let tag = tagName.toLowerCase();
	let props = ['text', 'html', 'self'];
	if(srcPropTags.includes(tag)){
		props.unshift('src');
	}
	if(hrefPropTags.includes(tag)){
		props.unshift('href');
	}
	return props;

};

const findElementByRoutes = (element, routes) => {
	let passRoutes = 0;
	let currentRoute = document;
	while(passRoutes < routes.length){
		let route = routes[passRoutes];
		let children = Array.from(currentRoute.children);
		passRoutes = passRoutes + 1;
		currentRoute = children[route.index];
	}
	return currentRoute;

};

const retrieveConfigData = (element, config) => {
	let routes = config.routes.slice(0, config.useRoute + 1);
	let target = findElementByRoutes(element, routes);
	return retrievePropData(target, config.useProp);

};

module.exports = {
	util: util,
	buildScrapeConfig: buildScrapeConfig,
	retrieveConfigData: retrieveConfigData

};